package com.yanqu.road.server.gameplayer.module.activity.guguoxunbao;

import com.yanqu.road.entity.activity.guguoxunbao.ExploreResult;
import com.yanqu.road.entity.activity.guguoxunbao.GuGuoXunBaoPlace;
import com.yanqu.road.entity.activity.guguoxunbao.GuGuoXunBaoTreasure;
import com.yanqu.road.entity.activity.guguoxunbao.GuGuoXunBaoUserData;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogGuGuoXunBaoExplore;
import com.yanqu.road.logic.bussiness.activity.GuGuoXunBaoBusiness;
import com.yanqu.road.pb.activity.GuGuoXunBaoProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.guguoxunbao.GuGuoXunBaoMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class GuGuoXunBaoModule extends GeneralModule {


    GuGuoXunBaoUserData userData;

    RandomHelper randomHelper = new RandomHelper();

    public GuGuoXunBaoModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        int activityId = GuGuoXunBaoMgr.getShowTimeActivityId();
        if (activityId != 0 && SystemOpenMgr.systemOpen(player, eSystemId.GuGuoXunBaoActivity.getValue())) {
            userData = GuGuoXunBaoBusiness.getUserData(player.getUserId(), activityId);
            if (userData == null) {
                initUserData();
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if(userData != null){
            if(userData.isInsertOption()){
                GuGuoXunBaoBusiness.addGuGuoXunBaoUserData(userData);
            }else if(userData.isUpdateOption()){
                GuGuoXunBaoBusiness.updateGuGuoXunBaoUserData(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        syncUserData();
    }

    public void syncUserData(){
        if(this.userData == null){
            return;
        }
        GuGuoXunBaoProto.GuGuoXunBaoDataSyncMsg.Builder syncMsg = GuGuoXunBaoProto.GuGuoXunBaoDataSyncMsg.newBuilder();
        GuGuoXunBaoProto.GuGuoXunBaoUserDataTemp.Builder dataBuilder = GuGuoXunBaoMgr.getUserDataBuilder(this.userData);
        syncMsg.setActivityId(GuGuoXunBaoMgr.getShowTimeActivityId());
        syncMsg.setUserData(dataBuilder);
        syncMsg.setConfigData(GuGuoXunBaoMgr.getConfigDataTempBuilder(player.getLanguage()));
        player.sendPacket(Protocol.U_GUGUOXUNBAO_ACTIVITY_SYNC_USER_DATA, syncMsg);
    }

    /**
     * 初始玩家数据
     */
    public void initUserData() {
        int showTimeActivityId = GuGuoXunBaoMgr.getShowTimeActivityId();
        if(showTimeActivityId == 0){
            return;
        }
        if(userData == null || (userData.getActivityId() != showTimeActivityId && showTimeActivityId > 0)) {
            GuGuoXunBaoUserData tempUserData = new GuGuoXunBaoUserData();
            tempUserData.setActivityId(showTimeActivityId);
            tempUserData.setUserId(player.getUserId());
            tempUserData.setInsertOption();
            tempUserData.setCurPlaceId(GuGuoXunBaoMgr.INIT_EXPLORE_PLACE_ID);

            userData = tempUserData;
        }
    }

    /**
     * 探索
     */
    public int explore(int type) {
        if(userData == null){
            return  GameErrorCode.E_GU_GUO_XUN_BAO_ACTIVITY_NO_UNLOCK;
        }
        ExploreResult result = new ExploreResult();
        List<GuGuoXunBaoProto.StateClueDataTemp> clueReward = new ArrayList<>();
        synchronized (userData){
            int times;
            String consume = GuGuoXunBaoMgr.CAMEL_ID + "=";
            if(1 == type){
                times = 1;
                consume = consume + 1;
            }else {
                times = 10;
                consume = consume + 9;
            }
            if(!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(consume), eLogMoneyType.GuGuoXunBaoActivity, eLogMoneyType.GuGuoXunBaoActivityConsume)){
                return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            }
            for(int i = 0; i < times; i++){
                explore(result, clueReward);
            }

            //排行
            player.notifyListener(eGamePlayerEventType.GuGuoXunBaoClueNumCrossRank.getValue(), userData.getAllClue());
            player.notifyListener(eGamePlayerEventType.GuGuoXunBaoClueNumRank.getValue(), userData.getAllClue());
            //成就，计算总价值
            long val = 0;
            for(Map.Entry<Integer, Long> entry : userData.getTreasureMap().entrySet()){
                GuGuoXunBaoTreasure treasure = GuGuoXunBaoMgr.getTreasureMap().get(entry.getKey());
                if(treasure != null){
                    val += entry.getValue() * treasure.getValue();
                }
            }
            player.notifyListener(eGamePlayerEventType.GuGuoXunBaoTreasureValue.getValue(), val);
        }

        GuGuoXunBaoProto.ExploreClueRespMsg.Builder respMsg = GuGuoXunBaoProto.ExploreClueRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setUserData(GuGuoXunBaoMgr.getUserDataBuilder(userData));
        if(!StringUtils.isNullOrEmpty(result.getComment())) {
            respMsg.setComment(result.getComment());
        }
        respMsg.addAllClueReward(clueReward);
        if(!result.getTreasureReward().isNothing()){
            respMsg.setTreasureReward(PropertyHelper.parsePropertyToString(result.getTreasureReward()));
        }
        respMsg.setReward(PropertyHelper.parsePropertyToString(result.getNormalReward()));
        respMsg.setType(type);
        player.sendPacket(Protocol.U_GUGUOXUNBAO_ACTIVITY_EXPLORE, respMsg);
        return 0;
    }

    /**
     * 探索一次
     */
    private void explore(ExploreResult result, List<GuGuoXunBaoProto.StateClueDataTemp> clueReward) {
        int oldPlaceId = userData.getCurPlaceId();
        List<Integer> placeIdList = new ArrayList<>();
        for(int pId : GuGuoXunBaoMgr.getPlaceMap().keySet()){
            placeIdList.add(pId);
        }
        int placeId = placeIdList.get(randomHelper.next(0, placeIdList.size()));
        int loop = 1000;
        while (oldPlaceId == placeId && loop > 0){
            loop--;
            placeId = placeIdList.get(randomHelper.next(0, placeIdList.size()));
        }
        Random random = new Random();
        int clueNumIdx = RandomHelper.getRandomIndexByWeight(GuGuoXunBaoMgr.getRandomWeight(), random);
        int clueNum = GuGuoXunBaoMgr.getRandomNum().get(clueNumIdx);
        GuGuoXunBaoProto.StateClueDataTemp.Builder clueDataTemp = GuGuoXunBaoProto.StateClueDataTemp.newBuilder();
        clueDataTemp.setPlaceId(placeId);
        clueDataTemp.setClueNum(clueNum);
        clueReward.add(clueDataTemp.build());
        GuGuoXunBaoPlace placeInfo = GuGuoXunBaoMgr.getPlaceMap().get(placeId);
        int num = 0;
        if (userData.getCurProgress().containsKey(placeId)) {
            num = userData.getCurProgress().get(placeId);
        }
        num = num + clueNum;
        //随机奖励(普通奖励)
        List<String> normalRewardList = new ArrayList<>();
        List<Integer> weightList = new ArrayList<>();
        GuGuoXunBaoMgr.extractPlaceReward(placeInfo, normalRewardList, weightList);
        random = new Random();
        int idx = RandomHelper.getRandomIndexByWeight(weightList, random);
        Property property = PropertyHelper.parseStringToProperty(normalRewardList.get(idx));
        result.getNormalReward().addProperty(property);

        //道具奖励入背包
        player.getModule(CurrencyModule.class).addCurrency(PropertyHelper.parsePropertyToString(property), eLogMoneyType.GuGuoXunBaoActivity, eLogMoneyType.GuGuoXunBaoActivityExploreGet);

      if (StringUtils.isNullOrEmpty(result.getComment())){
            result.setComment(GuGuoXunBaoMgr.getClueComment(clueNum, player.getLanguage()));
        }

        Property treasureProperty = new Property();

        //获得宝物个数
        int treasureNum = 0;
        if(num >= placeInfo.getClueNum()){
            treasureNum = num / placeInfo.getClueNum();
            num = num - placeInfo.getClueNum() * treasureNum;
        }
        if(treasureNum > 0){
            result.getTreasureReward().addProperty(placeInfo.getTreasureId(), BigInteger.valueOf(treasureNum));
            treasureProperty.addProperty(placeInfo.getTreasureId(), BigInteger.valueOf(treasureNum));
            userData.addTreasure(placeInfo.getTreasureId(), treasureNum);

            GuGuoXunBaoTreasure xunBaoTreasure = GuGuoXunBaoMgr.getTreasureMap().get(placeInfo.getTreasureId());
            if(xunBaoTreasure != null) {
                //其他奖励
                Property rewardProperty = PropertyHelper.parseStringToProperty(xunBaoTreasure.getRewards());
                rewardProperty.rideProperty(treasureNum);
                player.getModule(CurrencyModule.class).addCurrency(PropertyHelper.parsePropertyToString(rewardProperty), eLogMoneyType.GuGuoXunBaoActivity, eLogMoneyType.GuGuoXunBaoActivityExploreGet);
            }

        }
        userData.setCurPlaceId(placeId);
        userData.putCurProgress(placeId, num);
        userData.setAllClue(userData.getAllClue() + clueNum);

        //日志
        LogGuGuoXunBaoExplore exploreLog = new LogGuGuoXunBaoExplore(player.getUserId(), GuGuoXunBaoMgr.getShowTimeActivityId(), placeId,
                PropertyHelper.parsePropertyToString(property), clueNum, PropertyHelper.parsePropertyToString(treasureProperty));
//        LogMgr.addLogGuGuoXunBaoExplore(exploreLog);
        AutoLogMgr.add(exploreLog);
    }

    public GuGuoXunBaoUserData getUserData() {
        return userData;
    }

    /**
     * 系统解锁
     */
    public void initSystem() {
        if (userData == null) {
            initUserData();
            syncUserData();
        }
    }


}
